#pragma once

#include "CoreMinimal.h"

class UMBInstancedStaticMeshComponent;
class UMBInstancedBatchSubsystem;

enum EMBInstancedMeshType
{
	None,
	MovingPath, //行军路线
};

class FMBInstancedBatchProxyAbstract
{
public:
	FMBInstancedBatchProxyAbstract(){}
	virtual ~FMBInstancedBatchProxyAbstract(){}

public:
	UMBInstancedStaticMeshComponent* GetInstancedStaticMeshComponent();
	void SetStaticMesh(UStaticMesh* InStaticMesh);
	void SetInstancedMeshType(EMBInstancedMeshType InType){InstancedMeshType = InType;};
	EMBInstancedMeshType GetInstancedMeshType()const {return InstancedMeshType;};
	void BeginPlay(const UObject* WorldContext);
	void BeginDestroy();
public:
	virtual void ApplyCustomData(TArray<float>& PerInstanceSMCustomData) = 0;
	virtual void ApplyTransform(TArray<FTransform>& PerInstanceSMData) = 0;
	virtual int NumCustomDataFloats() = 0;
	virtual bool IsHidden() const {return false;}
	virtual bool IsRenderCustomDepth() {return false;}
	
	virtual  void SaveInstancedIndexes(const TArray<int>& InIndexes){InstancedIndexes = InIndexes;}
	virtual  const TArray<int>& GetInstancedIndexes()const {return InstancedIndexes; }

protected:
	TWeakObjectPtr<UMBInstancedStaticMeshComponent> InstancedStaticMeshComponent = nullptr;
	TWeakObjectPtr<UStaticMesh> StaticMesh = nullptr;
	EMBInstancedMeshType InstancedMeshType = EMBInstancedMeshType::None;
	TWeakObjectPtr<UMBInstancedBatchSubsystem> SubsystemWeaker = nullptr;
	TArray<int> InstancedIndexes;
};

class FMBInstancedBatchProxy : public FMBInstancedBatchProxyAbstract
{
public:
	void SetTransform(const FTransform& InTransform) {Transform = InTransform;}
	void SetNumCustomDataFloats(int32 InNumCustomData){
		NumCustomData = InNumCustomData;
		CustomDataFloats.SetNumUninitialized(NumCustomData);
	}
	TArray<float>& GetCustomDataFloats() {return CustomDataFloats;}
	void SetHidden(bool Value) {bHidden = Value;}
public:
	virtual void ApplyTransform(TArray<FTransform>& PerInstanceSMData) override {PerInstanceSMData.Add(Transform);}
	virtual void ApplyCustomData(TArray<float>& PerInstanceSMCustomData) override{
		for(const float& Value : CustomDataFloats){
			PerInstanceSMCustomData.Add(Value);
		}
	}
	virtual int NumCustomDataFloats() override {return NumCustomData;}
	virtual bool IsHidden() const override {return bHidden;}
protected:
	FTransform Transform;
	int32 NumCustomData = 0;
	TArray<float> CustomDataFloats;
	bool bHidden = false;
};